package cn.hamster3.mc.plugin.core.common.config;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings({"unused", "unchecked"})
@Getter
public class ConfigSection {
    @NotNull
    protected final Map<String, Object> map;

    public ConfigSection() {
        this(new HashMap<>());
    }

    public ConfigSection(@NotNull Map<String, Object> map) {
        this.map = map;
    }

    public boolean hasKey(@NotNull String key) {
        return map.containsKey(key);
    }

    @Nullable
    public ConfigSection getSection(@NotNull String key) {
        Object o = map.get(key);
        if (o instanceof Map) {
            return new ConfigSection((Map<String, Object>) o);
        }
        return null;
    }

    @NotNull
    public ConfigSection getSectionOrCreate(@NotNull String key) {
        Object o = map.get(key);
        if (o instanceof Map) {
            return new ConfigSection((Map<String, Object>) o);
        }
        ConfigSection section = new ConfigSection();
        map.put(key, section.map);
        return section;
    }

    @Nullable
    public String getString(@NotNull String key) {
        Object o = map.get(key);
        if (o == null) {
            return null;
        }
        return o.toString();
    }

    @NotNull
    public String getString(@NotNull String key, @NotNull String defaultValue) {
        Object o = map.get(key);
        if (o == null) {
            return defaultValue;
        }
        return o.toString();
    }

    public List<String> getStringList(@NotNull String key) {
        Object o = map.get(key);
        if (o instanceof List) {
            return (List<String>) o;
        }
        ArrayList<String> list = new ArrayList<>();
        map.put(key, list);
        return list;
    }

    public boolean getBoolean(@NotNull String key) {
        String string = getString(key);
        if (string == null) {
            return false;
        }
        return Boolean.parseBoolean(string);
    }

    public boolean getBoolean(@NotNull String key, boolean defaultValue) {
        String string = getString(key);
        if (string == null) {
            return defaultValue;
        }
        return Boolean.parseBoolean(string);
    }

    public int getInt(@NotNull String key) {
        String string = getString(key);
        if (string == null) {
            return 0;
        }
        return Integer.parseInt(string);
    }

    public int getInt(@NotNull String key, int defaultValue) {
        String string = getString(key);
        if (string == null) {
            return defaultValue;
        }
        return Integer.parseInt(string);
    }

    public float getFloat(@NotNull String key) {
        String string = getString(key);
        if (string == null) {
            return 0;
        }
        return Float.parseFloat(string);
    }

    public float getFloat(@NotNull String key, float defaultValue) {
        String string = getString(key);
        if (string == null) {
            return defaultValue;
        }
        return Float.parseFloat(string);
    }

    public double getDouble(@NotNull String key) {
        String string = getString(key);
        if (string == null) {
            return 0;
        }
        return Double.parseDouble(string);
    }

    public double getDouble(@NotNull String key, double defaultValue) {
        String string = getString(key);
        if (string == null) {
            return defaultValue;
        }
        return Double.parseDouble(string);
    }

    public long getLong(@NotNull String key) {
        String string = getString(key);
        if (string == null) {
            return 0L;
        }
        return Long.parseLong(string);
    }

    public long getLong(@NotNull String key, long defaultValue) {
        String string = getString(key);
        if (string == null) {
            return defaultValue;
        }
        return Long.parseLong(string);
    }

    public void set(@NotNull String key, @Nullable Object value) {
        if (value == null) {
            map.remove(key);
            return;
        }
        if (value instanceof ConfigSection) {
            ConfigSection section = (ConfigSection) value;
            map.put(key, section.map);
            return;
        }
        map.put(key, value);
    }
}
